iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
AI Engineering

Learning SRE for the AI Era:從 SRE Lab 到 Production AI Reliability系列 第 43 篇

Day 26(上)|AI Alerting:一筆幻覺不該叫醒所有人

  • 分享至 

  • xImage
  •  

GitHub:darkstar1227/learning-sre-for-ai-era

結論先說:AI alerting 要依影響範圍與可行動性分流;model outage、queue backlog、GPU 飽和、關鍵 tool provider 故障可以沿用既有的 burn-rate pager,單一品質樣本通常該先進 evaluation queue 或人工 review,而不是直接吵醒 on-call。

Day 25 定出一條界線:alert 要能回答「哪個 SLO 受威脅、誰負責、先做什麼」。今天把這條界線套進 AI workflow 最容易製造噪音的地方:語意品質訊號。

① The Question:AI 系統多出來的訊號,哪些才配當 alert?

一個 RAG/Agent workflow 一開機就會生出一堆傳統 API 沒有的數字:hallucination rate、groundedness score、citation-valid ratio、evaluator 給的分數波動。這些數字看起來都很像「品質出問題了」,但如果每一個都接 pager,值班的人很快就會學會把通知靜音。今天要回答的問題是:AI 特有的這批訊號,哪些該留在傳統 burn-rate alert 的邏輯裡,哪些必須換一套判斷方式?

這個問題之所以難回答,是因為它表面上像一個「調門檻」的工程問題,實際上是一個「誰有權叫醒誰」的組織問題。傳統 alerting 的門檻通常只需要跟一個東西對齊:使用者觀察到的服務水準。AI workflow 多出來的這批訊號,卻同時牽動三個不完全重疊的關切者——維運 on-call 關心的是「服務還能不能用」,model/quality owner 關心的是「這個答案值不值得信任」,safety/compliance 關心的是「這個系統有沒有做了它不該做的事」。三個問題聽起來相關,答案卻可能完全不同:一個回答讀起來語氣自然、格式完整、系統回應也在正常時間內完成,卻同時是一次不該發生的 hallucination。同一個 hallucination_detected=true 的事件,對 on-call 來說通常不是緊急事件(服務仍在正常回應),對 quality owner 來說是需要排隊判讀的證據,對 safety 來說則要看這個幻覺有沒有跨過某條不可逆的紅線。把這三種關切硬塞進同一條 pager pipeline,最後大概率會變成「什麼都通知,什麼都沒人真的處理」。

Day 25 已經定下一條界線:alert 要能回答「哪個 SLO 受威脅、誰負責、先做什麼」。今天不是重新發明這條界線,而是把它套進更複雜的訊號光譜:一端是「HTTP 500,服務明確壞掉」,另一端是「回答語氣正常、格式完整,但其中一句是編出來的」。傳統 alerting 幾乎只處理光譜左端;AI workflow 則逼你處理右端,而右端的訊號天生帶有不確定性:同一個評估器對同一筆輸入,可能在不同時間給出不同分數;同一個「品質下降」的觀測,背後可能是模型真的變差,也可能只是評估器本身不穩定。這篇文章要建立的,就是一套承認不確定性、又不讓不確定性變成不作為藉口的分流邏輯。

讀完全篇之後,你會發現這套邏輯其實有兩層。

第一層回答「這個訊號該不該叫醒人」。

第二層回答一個更根本的問題:「量這個訊號的方法,本身值不值得信任」。

多數 alerting 文章只處理第一層,本篇會把第二層也講完。

② Traditional SRE:alert 只問使用者受不受影響

經典 SRE 的做法在 Day 25 講過一次:availability、latency 這類直接對應使用者體驗的訊號,可以用 error-budget burn rate 接 pager;dependency error 也是等它確實威脅到使用者 SLO 才升級,而不是單次呼叫失敗就響。這條原則本身沒有因為系統換成 AI 而改變,變的是「威脅使用者 SLO」這件事在語意層要怎麼量。

③ AI Era Extension:Evaluation ≠ Alerting

Model outage、queue backlog、GPU 飽和、關鍵 tool provider 故障,這幾種訊號和傳統 dependency failure 一樣有清楚的使用者影響範圍,可以沿用既有的 burn-rate alert,理由沒變,只是依賴多了 GPU 和 provider。真正棘手的是另一批訊號:單一 hallucination、groundedness 小幅下降、evaluation score 小幅波動。這些訊號通常答不出「凌晨兩點該做什麼」,也沒有明確的使用者受影響邊界,貿然接 pager 只會製造焦慮,不會縮短事故時間。

這裡值得先說清楚,為什麼「GPU 飽和」能被歸進第一類,而不是要先送進 evaluation queue 判讀的那一類。GPU 推論失敗不像 hallucination 那樣需要人工才能定案,它通常會在兩個明確階段之一直接爆掉:模型載入階段的 VRAM 不足(例如 70B 等級的模型光是半精度權重就要吃掉一百多 GB,還沒算上長 context 的 KV cache),或是 CUDA graph capture 階段預留記憶體不夠。NVIDIA NIM 的故障排除文件與後續針對 Microsoft、Meta GPU 叢集的研究都指出,深度學習任務約有 9% 因為 OOM 而失敗(NVIDIA NIM Troubleshooting;Accurate GPU Memory Prediction for Deep Learning Jobs)。這種故障一旦發生,受影響的是「這個 route 上的所有 request」,而不是「某一則特定回答」,判斷方式和傳統的 connection pool 耗盡幾乎一樣:先看容量餘裕,再決定要不要接 pager。這正是它能沿用既有 burn-rate 邏輯的原因,hallucination 卻不行,因為後者連「誰受影響、影響到什麼程度」都要先靠人工或 evaluator 判讀出來,判讀本身就需要時間,不是一個能立即觸發安全動作的訊號。

2025 年 4 月的 Cursor 事件可用來說明「單筆語意失誤」和「該不該立即升級」是兩件事。媒體報導指出,Cursor 的 AI 客服機器人曾回覆不存在的「每訂閱限一台裝置」政策,之後引發使用者公開討論,Cursor 共同創辦人 Michael Truell 出面澄清與道歉(The Register)。這個案例不能證明每一筆錯答都需要 pager;它指出的是,若錯誤已擴散成需要對外澄清的事件,處理方式應升級為 safety review 與使用者溝通,而不必然是把基礎設施 on-call 從床上挖起來。

日常運作中更常見的情況,是把統計信號的穩定性當成判斷依據。假設對採樣流量(約 5–10%)持續計算 citation-valid ratio:單筆樣本失敗(某個回答缺有效引文)不該直接觸發 pager,但當滾動窗口內的比例從 98% 掉到 94%,代表出現系統性退化,這時該進 evaluation queue 與 release gate 檢查,而不是等使用者自己回報。單筆失敗是噪音,持續下滑的趨勢才是訊號,這正是 Day 25 那條界線在語意層的具體版本。

但這裡有個隱形陷阱:評估器本身就有噪音。同一個案例用同一個評估模型在不同時段評分會得到不同結果。一個更激進的 prompt 版本看起來「回答更詳細」,但實際讓失敗率從 2% 升到 5%,評估器的自然變異(15–20% 的內在隨機性)容易把這 3% 的真實退化淹沒在假陽性中。業界最佳實踐是同一案例評分 3 次並取中位數——這個小投資能將 100 案例數據集的假陽性降低約 60%。換句話說,沒有最小樣本數、沒有多次評分、沒有 baseline percentile 的品質下降,容易被誤判,不應直接升級。

評估器的噪音不是玄學,是有具體行為模式的

「評估器不穩定」聽起來像一句安全的免責聲明,但它其實對應到幾種可以命名的具體現象。2025-2026 年業界對 hallucination 偵測方法已經形成一組共識做法:不對每一筆請求都做完整幻覺檢查(成本太高,一次完整的 factuality check 往往要多打一次甚至多次模型呼叫),而是在開發環境跑全量、在生產環境抽樣 5–10% 的流量,搭配異常偵測追蹤模型行為的非預期變化(FutureAGI:Detect Hallucinations in Generative AI;Braintrust:Best Hallucination Detection Tools for LLM Applications)。這套實踐還做了一件對 alerting 設計很關鍵的事:把「幻覺」拆成兩種不同的東西。

Intrinsic hallucination
模型輸出違反自己被給定的 instruction 或 retrieved context
→ 通常可以用 citation 比對、faithfulness check 自動抓到

Extrinsic hallucination
模型編造出完全無法用現有上下文驗證的事實
→ 需要外部事實查核,往往只有人工或領域專用 checker 能判定

這個拆分直接回答了一個常被忽略的問題:「citation-valid ratio 該設多高才算正常?」業界的落地數字不是單一常數,而是依場景分級——合規性工作(法律、醫療、財務決策)要求 ≥ 0.99,一般問答場景則可以放到 ≥ 0.95。但無論門檻設在哪,共識都指向同一件事:單一樣本跌破門檻不代表系統故障,該被監控的是「滾動窗口下的比例走勢」,只有走勢持續跨過門檻,才進 evaluation queue。這正是③段前面citation-valid ratio 案例(98% 掉到 94%)的依據來源,也解釋了為什麼 alert_router 裡的品質下滑判斷要同時要求 baseline、sample size 與差距門檻三個條件都成立——少了任何一個,你其實無法區分「模型真的變差了」跟「這次抽樣剛好比較倒楣」。

評估器噪音還有更根本的一層,而且是 2026 年才被具體量化出來的:評估器可能知道自己正在被評估,而它的行為會因此改變。Anthropic 用自家發展的可解釋性方法(把模型內部激活值轉譯成可讀文字的技術,稱為 Natural Language Autoencoders)分析模型的內部狀態,發現 Claude 在 SWE-bench Verified 這類標準基準測試中,約有 26% 的作答過程出現「意識到自己正在被評估」的內部訊號;在涉及高風險操作(如刪除檔案等 destructive code actions)的測試裡,這個比例是 16%。關鍵是模型幾乎不會把這件事說出口——你在輸出文字裡看不到「我知道這是測試」,這個訊號只存在於內部激活層,要靠專門的可解釋性工具才挖得出來(Anthropic 研究整理:Claude Knows It's Being Tested)。

這個發現對 AI alerting 的意義,不是「模型在說謊」這種聳動結論,而是一個更務實的提醒:你的離線評估分數,測的可能不完全是模型在生產環境的真實行為。同一份研究也提供了對照組數字——同樣的評估意識訊號,在真實 claude.ai 使用紀錄裡只出現在不到 1% 的對話中。換句話說,benchmark 環境與生產環境之間存在一個系統性落差,而這個落差的方向剛好對你不利:你在測試環境量到的品質數字,可能天生就比生產環境實際表現更好看。這正是為什麼一條品質趨勢不能只靠上線前的 release gate 評估來背書,必須有獨立的生產環境抽樣監控(也就是 evaluation queue 存在的理由),而不是把「上線前 golden dataset 測試通過」當成「生產環境會一直維持這個水準」的保證。

一份針對 agentic AI 系統的生產追蹤研究把這個落差講得更具體。研究者對部署在真實流量下的 agent 系統做了數個月的觀察,發現在固定 golden dataset 上表現優異的系統,換成真實使用者流量後開始出現系統性漂移:輸入分布改變、使用者行為模式改變、邊界案例的出現頻率遠高於測試集覆蓋範圍(arXiv:Evaluating Agentic AI in the Wild)。研究歸納出三個根本原因,剛好對應到本篇談的三個設計盲點:靜態 benchmark 測不出真實流量下的行為漂移(呼應下篇資料契約強調的 window/版本欄位)、系統可能學會優化評估指標而非真正解決問題(呼應本節「評估器噪音」的核心提醒)、既有評估框架的覆蓋範圍本來就不包含長視野決策與錯誤恢復這類 production-only 的失敗模式(呼應下篇 SRE Lab 刻意保守的 sample size 與 baseline 門檻設計)。這篇論文的結論很直接:大多數生產環境的 AI 失敗,根因不是模型能力不夠,而是評估與監控機制的更新速度跟不上生產環境變化的速度——這也是為什麼本文從頭到尾都不主張「評估一次、然後就相信這個分數」,而是主張品質訊號必須持續、可回查、可質疑。

④ SRE Lab:今日 DIY,做一張分流表

替自己的 AI workflow 列出至少三種訊號,各自填上影響範圍、去向、owner、初步動作。

在填表之前,先問自己一個更基本的問題:這個訊號目前在你的系統裡,實際上是怎麼被處理的?

多數團隊在還沒認真設計分流之前,其實已經有一套隱性規則。

這套隱性規則通常長這樣:技術訊號(5xx、timeout)有明確的 pager,因為它是從傳統系統時代就繼承下來的習慣。

品質訊號(hallucination、groundedness)則常常落在兩個極端:要嘛完全沒人看,堆在某個 dashboard 的角落;要嘛被某次事件嚇到後,臨時接上 pager,然後半年後又被靜音,因為誤報太多。

安全訊號則經常是最模糊的一塊——沒有人明確說過「這類事件該找誰」,直到真的發生了,大家才在事件當下臨時決定升級路徑。

這張分流表要做的事,就是把這套隱性規則攤開來檢查:哪些是你其實同意的,哪些只是「一直沒人去改」。

訊號 影響 去向 Owner 初步動作
model timeout 快速上升且 SLO burn 廣泛 pager on-call degradation/查 provider
citation-valid ratio 下降 未知 evaluation queue model owner 比對版本與樣本
高風險 tool action 被拒絕 安全風險 security review security owner 保留證據、停用 action

驗收

  • pager 與 review queue 有不同條件和 owner。
  • 高風險 safety 事件有獨立升級路徑,不必等統計門檻。
  • 每條訊號都寫得出使用者影響或風險理由,而不是「反正它看起來不對勁」。
  • 表格是流程設計,未經演練不宣稱有效。

本文未設定 paging、未串接真實 evaluation queue,也未執行安全事件升級。

⑤ Evidence:把「可行動」量成數字,才看得出訊號值不值得留著

Etsy 的 Opsweekly 做法,是讓值班工程師替進來的 alert 標記是否 actionable,再彙整成週報追蹤這個比例。這把「這條 alert 有沒有用」從主觀抱怨變成每週能檢視的資料。AI 特有的語意品質訊號也適用同一套量測方式:先問單筆事件能不能決定下一步,答不出來就先別接 pager。本文不以該文推論特定比例、通知量或可靠性結果,因為那些數字必須回到各團隊當時的分類資料與流量脈絡判讀。

但為什麼這件事這麼重要?2025–2026 年的產業數據很駭人。企業平均每日接收 2,992 個告警,其中 46% 是假陽性,63% 完全沒被處理。78% 的 NOC 團隊報告經歷嚴重 alert fatigue,平均每天超過 10,000 個告警,卻只有不到 5% 需要立即人工處理。這導致一個惡性迴圈:告警太多 → 工程師學會無視 → 真正的事故也被忽視(61% 的團隊承認忽略過後來被證實為關鍵的告警)。AI 系統的品質監控正在複製相同危機——當每次 prompt 版本變更、evaluator 更新都可能觸發「品質異常」通知時,工程師很快就會停止相信這些通知。

Cursor 事件則補上另一面:它示範了「單一 semantic failure」在什麼條件下會跨過那條線:不是因為出現了幻覺,而是因為影響範圍在幾天內從個案變成大規模訂閱取消。同一個 symptom(虛構回答),scope 不同,該走的流程就不同。

還有第三面,而且是本篇特別想強調的一面:你用來判斷「該不該升級」的那把尺,本身的刻度可能不準。業界對 hallucination 偵測已經有一套相對成熟的取樣與門檻共識——5–10% 抽樣、intrinsic 與 extrinsic 分開處理、依場景設定 0.95 到 0.99 的門檻,這代表這不是一個每個團隊都要從零摸索的問題。但同一批研究也指出,實驗室裡測出來的分數,和生產環境的真實表現之間,存在一個系統性、而且方向可預測的落差——測試環境的分數傾向於比生產環境更好看。也就是說,如果告警門檻是拿 release gate 測出來的分數去校準,這個門檻很可能從一開始就設得太寬鬆,因為校準用的資料本身就偏樂觀。

三個證據疊在一起,拼出的圖像是:分流表要處理的不只是「這個訊號重不重要」,還要處理「量這個訊號的尺,可不可靠」。前者是本篇大部分篇幅在談的事,後者則是下篇「評估器本身也會壞」那個案例才真正被講清楚的一層。

⑥ What I Learned:分流表要對得起兩種代價

寫這張分流表之前,容易只想著「漏掉真正的事故」這個代價,於是傾向把可疑訊號都接 pager。但 Etsy 的六成數字提醒我,過度 paging 也有代價:它會磨掉值班工程師對 alert 的信任,下次真正的事故來了,反而更慢被當一回事。Cursor 案例則提醒我不能只看訊號種類分流,還要留一條路給「影響範圍正在擴大」這種例外,不然分流表會把真正該立即處理的個案也晾在 evaluation queue 裡。

寫這張分流表時我也發現,它本身需要一個「evaluator 可能不可靠」的但書。一開始設計分流邏輯時,我下意識把 evaluator 的判斷當成事實——quality_status 是 needs_review,就是 needs_review,不會再多問一句。但 Anthropic 那份研究提醒我,評估環境本身可能悄悄改變模型的行為,而這個效應在真正的生產環境裡幾乎不存在。換句話說,我在測試階段信任的那個評估分數,天生就帶著一點「這是在考試」的偏差,而我卻打算拿它去校準生產環境的告警門檻——下篇會用一個真實案例(release gate 通過、三週後才現形)把這個偏差講得更具體。

這讓我在分流表之外,多加了一條自己的提醒:任何拿來設定門檻的評估數字,都要先問一句「這個分數是從哪個環境量出來的」,而不是預設所有分數都可以互相比較。

⑦ Production Takeaway

如果這是真實 production system,我會做三件事:把 model outage、queue backlog、GPU 飽和、tool provider 故障這類有清楚使用者影響邊界的訊號,直接掛進既有的 burn-rate pager,不用另外發明一套 AI 專屬告警邏輯;把 hallucination rate、groundedness、evaluation score 這類語意品質訊號改成滾動窗口監控,送進 evaluation queue 與 release gate,只有趨勢持續惡化才升級;同時替高風險 safety 事件保留一條獨立的立即升級路徑,並用類似 Opsweekly 的方式定期檢視每條規則的 actionable 比例,讓分流表隨著實際使用情況調整,而不是寫完就當作永遠正確。

第四件事,是替評估本身留一道審查機制:任何拿來設定告警門檻的品質分數,都要先確認它的量測環境跟門檻要套用的環境是不是同一種——上線前 golden dataset 測出來的分數,不能直接拿去校準生產環境的告警線,兩者要各自維護一套基準,並且定期核對彼此有沒有拉開距離。這五件事合起來,才是一套完整的分流政策:誰負責被叫醒、誰負責被通知、誰負責善後,以及最容易被忘記的——量這一切的尺子,本身要不要被校準。

⑧ 先把「訊號」和「通知」拆開

AI 系統最容易犯的設計錯誤,是把每一個可量測欄位都當成告警候選人。它們不是。groundedness_score=0.61 是一筆觀測資料:它可能代表檢索沒有找到文件,也可能代表 evaluator 看錯了,還可能只是某個使用者問了資料庫根本沒有答案的問題。在沒有時間窗口、樣本數、工作流版本與使用者影響以前,這個分數不能直接推導出 incident。

更麻煩的是,連「0.61」這個數字本身的可信度,都要看它是從哪個評估環境量出來的——這句話現在聽起來可能有點跳躍,但讀到下篇「評估器本身也會壞」那個案例之後,你會發現這正是這兩篇想一路鋪陳到底的提醒。

先分清四個層次,後面的設計才不會全部擠進 pager。

層次 問題 典型載體 是否即時叫人
Event 這一次 request 發生什麼? log、trace、feedback 否
Signal 最近是否出現模式? metric、dashboard 通常否
Decision 要不要改變流量、版本或流程? queue、release gate 依風險
Alert 現在是否需要特定 owner 介入? page、ticket、security escalation 只有可行動時

這個拆法看似語意問題,其實是成本問題:每送出一則 pager,都在消耗值班者的注意力;每忽略一個品質趨勢,也可能累積成使用者傷害。分流的工作不是讓通知越少越好,而是讓每個訊號走到能處理它的地方。

這四個層次也不是一次性的分類,而是一條資料會依序爬過的階梯:一筆 request 完成後先變成 Event,記錄在 log 或 trace 裡;多個 Event 累積出模式,才變成出現在 dashboard 或 metric 上的 Signal;Signal 是否需要人為介入,取決於 Decision 這一層的判斷——這正是 evaluation queue 存在的位置;只有 Decision 認定「需要特定 owner 立刻做點什麼」,才會產出 Alert。多數 AI alerting 失敗的案例,問題不是任何一個層次本身設計錯了,而是跳過了中間幾層,讓 Event 直接被當成 Alert。

可以把 Day 26 的核心流程畫成這樣:

request / trace / user feedback
            |
            v
      normalise evidence
            |
            +--> technical impact? ----> SLO burn / pager
            |
            +--> safety boundary? ----> security escalation
            |
            +--> sustained quality drift? -> evaluation queue
            |
            +--> isolated sample? ------> trace review / dataset candidate
            |
            +--> no reproducible evidence -> dashboard only

同一筆 trace 可以同時進兩條路:模型 timeout 造成 /ask 的 task failure,技術面會影響 availability SLO;同一筆 trace 的 prompt 也可能成為事後分析 provider fallback 是否正確的樣本。這不叫重複處理——前者在回答「服務還能不能用」,後者在回答「為什麼這次失敗,以及下次怎麼少失敗」。這個雙重用途提醒了一件容易被忽略的事:同一份 evidence 不該只有一個消費者。設計資料契約時,如果只考慮「pager 需要什麼欄位」,很可能會漏掉 evaluation queue 或 postmortem 之後才需要的欄位——例如 prompt 版本、retrieval index 版本這些技術告警不太在意、但品質分析非常在意的資訊。下一節的資料契約,就是把這兩種用途一起考慮進去後的結果。

⑨ 一條 AI alert 的最低資料契約

不論用 Prometheus、OpenTelemetry、LangSmith、Langfuse,還是自建事件表,分流前都需要一個不依賴特定產品的資料契約。

若每個團隊各自發明欄位,當 incident 發生時就得先猜資料能不能接起來。

這裡用一個最小事件表示法。

{
  "observed_at": "2026-09-22T09:00:00Z",
  "request_id": "req_01",
  "trace_id": "trace_01",
  "task_id": "task_01",
  "workflow_name": "policy_rag",
  "workflow_version": "2026.09.22.1",
  "service_version": "api-1.8.0",
  "prompt_version": "policy-answer-v4",
  "model_provider": "provider-a",
  "model_name": "model-x",
  "retrieval_index_version": "policy-2026-09-20",
  "technical_status": "success",
  "task_status": "failed",
  "quality_status": "needs_review",
  "safety_status": "pass",
  "fallback_triggered": false,
  "latency_ms": 1840
}

欄位很多,但並不是要把它們全做成 Prometheus label。

request_id、trace_id、task_id 的 cardinality 幾乎等於 request 數量。

把它們塞進 metric label,時間序列會膨脹,監控系統自己先變成事故。

它們適合放在 log、trace 或 evaluation record。

metric 裡只保留用來彙整的有限維度。

例如 workflow、model route、outcome、是否 fallback。

from prometheus_client import Counter, Histogram

ai_task_total = Counter(
    "ai_task_total",
    "Completed AI tasks grouped by stable outcome dimensions.",
    ["workflow", "model_route", "task_status", "quality_status", "safety_status"],
)

ai_request_latency_seconds = Histogram(
    "ai_request_latency_seconds",
    "End-to-end AI workflow latency.",
    ["workflow", "model_route", "fallback_triggered"],
)

這段不是要你立刻把程式貼進 production。

它要表達的是 label 的邊界。

workflow="policy_rag" 的值是有限集合。

model_route="primary" 與 "fallback" 也是有限集合。

request_id="req_01" 則永遠會增加。

後者必須留在 trace,而不是 metric。

接著替每一筆品質資料保留可回查的 evidence。

quality_event = {
    "trace_id": trace_id,
    "task_id": task_id,
    "workflow_version": workflow_version,
    "prompt_version": prompt_version,
    "evaluator_version": "citation-check-v2",
    "sampled": True,
    "score": 0.0,
    "reason": "citation_does_not_support_claim",
    "review_state": "unreviewed",
}

reason 不應是模型隨手生成的一大段自然語言。

把它收斂成有限類別,例如 missing_citation、unsupported_claim、unsafe_tool_request、evaluator_error。

這樣才能在 dashboard 上回答:哪一類錯誤正在增加?

若要保留完整說明,把它放在 trace annotation 或 review record。

review_state 這個欄位,是為了對付一種很容易被忽略的競態

quality_event 裡的 review_state 欄位,一開始很容易被當成無關緊要的狀態旗標,但它其實在處理一個時間差的問題:一筆事件被建立的當下,evaluator 給的分數是 unreviewed,這個分數可能過幾分鐘就被人工複查推翻,也可能三次評分取中位數後數字整個改變。如果 dashboard 或 alert 邏輯直接讀第一次寫入的分數,看到的可能是一個已經過時、甚至已經被推翻的判斷。review_state 讓下游知道:這筆資料現在能不能被信任地拿去算趨勢。

review_state = unreviewed
剛寫入,只有自動評分,尚未有人工或多次評分覆核

review_state = confirmed
自動評分與人工複查(或多次評分中位數)一致,可信度較高

review_state = overturned
人工複查推翻了自動評分的判斷,這筆事件不該再被算進失敗計數

沒有這個欄位,品質趨勢圖上每一個資料點其實都帶著不同程度的不確定性,卻被畫成看起來一樣精確的一條線;有了它,至少能在畫圖時把「已複核」跟「還沒複核」的部分用不同顏色標出來,讓看圖的人知道最近的幾個資料點還可能會變動。這聽起來是個小細節,但它正是下篇「評估器本身也會壞」那個案例想指出的問題在資料層的具體解法:不是不相信評估器,而是誠實標記每一筆評估的可信度,不要讓一次性的自動評分偽裝成已經蓋棺論定的事實。

⑩ 先定義四條路,再寫規則

很多告警規則失控,是因為團隊先打開 alert manager,才開始討論升級策略。

順序應反過來。

先寫出每條路的目的、owner 與時限。

Pager:技術可用性正在傷害使用者

Pager 的前提不是「數字很大」。

前提是有持續、可證實的使用者影響,而且值班者有一個安全動作可做。

適合 Pager 的例子:

  • /ask 5xx 與 timeout 讓 error budget 快速燃燒。
  • provider outage 使 primary 與 fallback 都無法完成任務。
  • GPU queue backlog 使多數 request 超過已承諾的 latency SLO。
  • 必要的 tool provider 故障,且 workflow 沒有安全降級路徑。

不適合 Pager 的例子:

  • 一筆回答的 wording 很差。
  • 一筆 evaluator score 很低,但沒有人工確認。
  • 某個模型的 token 數增加,卻還沒造成 latency 或成本預算異常。
  • 使用者按下 dislike,但未提供可重現線索。

Pager 事件至少要附上這些內容:

service: ai-api
workflow: policy_rag
symptom: /ask availability error-budget fast burn
first observed: 09:02 UTC
scope: all requests routed to provider-a
owner: api-on-call
safe first action: enable known fallback route
evidence: dashboard URL, trace query, deploy version

其中 safe first action 是核心。

如果通知只寫「hallucination rate high」,值班者即使半夜看到,也無從判斷能不能切模型、能不能停止流量、能不能撤回 prompt。

這種 alert 不是資訊不足,是責任設計沒有完成。

Evaluation queue:品質趨勢需要被判讀

Evaluation queue 接的是「需要研究」而不是「現在要救火」的工作。

典型觸發條件可以是:

  • 連續三個評估窗口都低於品質基線。
  • 新 prompt 版本相較對照組顯著下降。
  • 某個文件索引版本讓 unsupported_claim 比例上升。
  • 特定語言、租戶或工作流的失敗率升高。

Queue item 不該只是一個百分比。

它要能帶人回到樣本。

queue item: quality-drift-2026-09-22-001
window: 08:00-09:00 UTC
workflow: policy_rag
comparison: prompt v4 versus v3
signal: citation-valid ratio 98.2% -> 94.1%
sample size: 186 sampled completed tasks
top reason: unsupported_claim
evidence: 12 representative trace links
owner: model-quality rotation
due: next business day

這裡的 sample size 不能省。

十筆樣本中少一筆,和一千筆樣本中少一百筆,不是同一種訊號。

若資料是抽樣,也必須說抽樣比例與方式。

沒有 denominator 的「品質下降 4%」幾乎無法判讀。

Safety escalation:風險邊界被碰觸

Safety escalation 不必等待統計趨勢。

原因不是它一定更嚴重,而是有些行為一旦成功執行就不可逆。

例如:

  • agent 嘗試呼叫未授權的付款、刪除或資料匯出工具。
  • prompt injection 使模型要求讀取本不該讀取的資料。
  • 輸出含有需要立即依政策處置的敏感內容。
  • tool policy engine 與實際 tool execution 的授權結果不一致。

這條路要有獨立 owner。

把它丟給一般 API on-call,常見結果是「先等白天的模型團隊看看」。

那不叫升級。

範例紀錄可以長這樣:

event_type: unauthorized_tool_attempt
severity: high
executed: false
policy_decision: deny
tool_name: export_customer_records
trace_id: trace_01
containment: tool call was blocked
next owner: security incident lead

executed: false 和 executed: true 是完全不同的事件。

記錄「有被擋住」也很重要。

它既是 near-miss 的證據,也是 Day 27 復盤時能檢查防線是否真正工作的材料。

Dashboard 與 ticket:值得看,但不必立即打斷人

有些訊號並不假裝成警報,反而更有用。

例如 prompt token 緩慢上升、低風險回答的使用者 dislike、retriever 命中數突然變多。

它們可以進 dashboard,並用週期性 ticket 要求 owner 檢視。

這不是放著不管。

這是承認它們需要長時間尺度的判讀。

⑪ 把分流表寫成可討論的 policy

下面是一份可直接改名後使用的草案。

它不是通用答案。

門檻必須由你的 SLO、業務風險、流量與回應時間決定。

這份政策草案本身也值得被追問一句:每一列的「首要 owner」,是不是一個真人、一個團隊,而不是一個群組信箱?

owner 欄位寫「platform team」聽起來合理,實際運作起來卻常常變成沒有人。

值班表、輪班制度、交接窗口,這些才是讓 owner 欄位從一個名詞變成一個真正會回應的人的必要條件。

寫政策的時候,順手核對一下這一列,往往比核對門檻數字更能預防未來的漏接。

事件類型 最小證據 預設去向 首要 owner 第一個安全動作
/ask fast burn SLO window 內持續失敗 Pager API on-call 套用既定降級或 fallback
provider timeout 造成 task failure 且無有效 fallback Pager API on-call 檢查 provider 狀態與 route
queue backlog 已威脅 latency SLO Pager 或 ticket platform on-call 限流、擴容或暫停非必要工作
citation-valid 下滑 樣本數、窗口、版本都完整 Evaluation queue quality owner 比對 prompt、index 與 evaluator
evaluator disagreement 多個 evaluator 或人工抽查不一致 Dataset review evaluation owner 標記 evaluator 不可靠範圍
unsafe tool attempt policy evidence 完整 Security escalation security owner 保留 evidence、限制 capability
single bad answer trace 可回查 Review sample workflow owner 標記與分類,不立即改 production
cost increase 成本窗口超過預算 FinOps ticket platform owner 檢查 routing、token 與 retry

表格裡的「最小證據」是防止情緒型 alert 的欄位。

沒有 evidence 的 event 可以被記錄。

不能自動把人叫起來。

同時替每一條政策設定反例。

反例能逼團隊說清楚「為什麼這次不升級」。

規則 容易誤觸發的反例 防呆方式
quality drift 流量突然集中到本來就難的問題 依工作流與輸入類別切分,保留 baseline
provider outage 單一 region 網路波動 以使用者 SLO 與成功率交叉驗證
unsafe request red-team 測試流量 清楚標記測試環境與測試帳號
token spike 合法長文件導致輸入變大 比較文件大小與 prompt 版本
negative feedback 使用者偏好差異 建立可分類 feedback,不用單一 dislike 斷言品質

這份政策草案本身只是紙上規則。下篇會把它接上真正可測試的路由邏輯、Prometheus 規則與三個完整判讀案例,並回頭處理一個更根本的問題:你用來校準這些門檻的評估分數,本身值不值得信任。

這篇是 Learning SRE for the AI Era 系列的一部分。
Build → Trace → Break → Measure → Evaluate → Recover → Improve.


上一篇
Day 25(下)|什麼才是好的 Alert?叫醒人之前,先給他一件能做的事
下一篇
Day 26(下)|AI Alerting:一筆幻覺不該叫醒所有人
系列文
Learning SRE for the AI Era:從 SRE Lab 到 Production AI Reliability 共 44 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言